home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 November: Tool Chest / Dev.CD Nov 94.toast / Apple II / System 6.0 Sample Code / CDevTester / CDevTester.c next >
Encoding:
C/C++ Source or Header  |  1993-06-15  |  16.9 KB  |  572 lines  |  [TEXT/MPS ]

  1. /*###########################################################*/
  2. /*#                                                                            #*/
  3. /*#    File:            CDevTester.c                                        #*/
  4. /*#    Version:        1.0                                                    #*/
  5. /*#    Author:                                                                #*/
  6. /*#    Copyright:        (c) 1991 by Apple Computer, Inc.            #*/
  7. /*#                                                                            #*/
  8. /*#    Description:    This file contains the cdev C                #*/
  9. /*#                    routine used by the CDevTester CDEV.        #*/
  10. /*#                                                                            #*/
  11. /*#---------------------------------------------------------#*/
  12. /*#                                                                            #*/
  13. /*#    Development History:                                                #*/
  14. /*#                                                                            #*/
  15. /*#    Who        Date        The Modification                            #*/
  16. /*#    ---        --------    ----------------                            #*/
  17. /*#    RAH        03/27/91    Initial release                            #*/
  18. /*#                                                                            #*/
  19. /*###########################################################*/
  20.  
  21. #include <Types.h>
  22. #include <GSOS.h>
  23. #include <Quickdraw.h>
  24. #include <Font.h>
  25. #include <Memory.h>
  26. #include <IntMath.h>
  27. #include <Event.h>
  28. #include <ProDOS.h>
  29. #include <Locator.h>
  30. #include <Control.h>
  31. #include <Window.h>
  32. #include <List.h>
  33. #include <Scrap.h>
  34. #include <Dialog.h>
  35. #include <Menu.h>
  36. #include <Desk.h>
  37. #include <StdFile.h>
  38. #include <QDAUX.h>
  39. #include <Print.h>
  40. #include <MiscTool.h>
  41. #include <LineEdit.h>
  42. #include <Resources.h>
  43.  
  44. #include <malloc.h>
  45. #include "CDevTester.h"
  46. #include "rDefs.h"    
  47.  
  48. extern unsigned SaveDB ();
  49. extern void        RestoreDB ();
  50.  
  51. /* Some globals */
  52.  
  53. int            OriginalKeyRepeatRate;
  54. int            UpdateFlag = 0;
  55. CtlRecHndl    CDevCtlHandle;
  56. CtlRecHndl    TimeCtlHandle;
  57. CtlRecHndl    AboutBoxCtlHandle;
  58. WindowPtr     MyCDevWindowPtr;
  59. WmTaskRec    myTaskRec;
  60.  
  61.  
  62. /* Declare a text buffer to hold the ASCIITimeCtl, a static text control which points to the text */
  63. /* buffer, and a handle to create the control. These are used to display the time that show that */
  64. /* the RunCDev message is being passed. */
  65.  
  66. static char         ASCIITimeText[30];
  67.  
  68. StaticTextTemplate ASCIITimeCtl =    {
  69.                                                 8,                                /* p count */
  70.                                                 100L,                            /* control ID */
  71.                                                 {130,25,145,185},            /* ctl rect */
  72.                                                 (long) statTextControl,    /* procRef */
  73.                                                 0x0001,                        /* flag */
  74.                                                 0x1000,                        /* moreFlags */
  75.                                                 0L,                            /* refCon */
  76.                                                 (Ref) ASCIITimeText,        /* textref */
  77.                                                 20                                /* textSize*/
  78.                                                 };
  79.  
  80. /*###########################################################*/
  81. /*#        Actual CDEV, this is called by the control panel    #*/
  82. /*###########################################################*/
  83.  
  84. /* This routine is eventually linked and then placed into a cdev code resource.
  85.   The only requirements are that this routine is at the beginning of the resource
  86.   so if the CDEV has any other routines they must follow this one.  The cdev's resource
  87.   fork is always opened when a call to the cdev is made.  The cdev can also assume
  88.   that the current port is set to the ctl panel window except in the boot message,
  89.   where quickdraw isn't even started, and in the about message, where it is the port
  90.   of the help window.  All normal managers will be stared up for all calls except
  91.   the boot call, which will only have miscTools & Resource Manager started. */
  92.  
  93. pascal long CDEV(message,data1, data2)
  94. int    message;
  95. long    data1;
  96. long    data2;
  97. {
  98.     unsigned                oldDBR;
  99.     int                    retCode;
  100.     static char            AlertString[175];
  101.     
  102.     oldDBR = SaveDB();    /* set up DBR correctly */
  103.     
  104.     retCode = 0;    /* initialize the function result to zero, so that we will work in
  105.                         future versions of the Control Panel! */
  106.  
  107.  
  108.     switch(message)
  109.         {
  110.             case MachineCDEV:    /* Message 1 */
  111.  
  112.                 /* This is called if the wantMachine bit is set in the CDEV flags.
  113.                   It enables the CDEV to do further checking to see if it makes
  114.                   sense for the CDEV to be visible to the user or not.  For instance,
  115.                   if the CDEV controls a setting for some hardware, we could check to
  116.                   see if the hardware is really connected.  The parameters are undefined
  117.                   for this call and the result is passed back as the function result.  0 =
  118.                   don't show this CDEV, <>0 = show this CDEV.  The control panel will do
  119.                   some machine checking even before calling this routine by checking the
  120.                   ROM version number against the machine field of the cdev flags resource */
  121.                       
  122.                 retCode = MachineCDEVProc();
  123.                 break;
  124.     
  125.             case BootCDEV:    /* Message 2 */
  126.  
  127.                 /* if the wantBoot flag is set, this routine will be called during the
  128.                   startup sequence.  The control panel takes care of drawing the "boot"
  129.                   icon.  When this call is made, the machine state is bad at best.
  130.                   QuickDraw is not even started up.  The parameters to this call are
  131.                   undefined. */
  132.     
  133.                 break;
  134.     
  135.             case ShutDownCDEV:    /* Message 3 */
  136.             
  137.                 /* if the wantShutDown bit is set in the CDEV flags resource then
  138.                   this routine is called when the user either disables the CDEV or
  139.                   *someday* when the machine is being turned off.  It gives the CDEV
  140.                   a chance to turn itself off (or any hardware or software it controls).
  141.                   The parameters are undefined in this call. */
  142.     
  143.                 break;
  144.         
  145.             case InitCDEV:    /* Message 4 */
  146.  
  147.                 /* if the wantInit flag is set, then this message is passed with data1 =
  148.                   the control panel's Window ptr.  By  this time the CreateCDEV call
  149.                   will have been made and thus the controls used by the CDEV created.
  150.                   This call enables the CDEV to initialize the controls before they are
  151.                   displayed. */
  152.                 
  153.                 InitCDEVProc (data1);
  154.                 break;
  155.     
  156.             case CloseCDEV:    /* Message 5 */
  157.  
  158.                 /* The CloseCDEV message is passed if the wantClose bit is set in the CDEV
  159.                   flags and the control panel is closing or when the user selects another
  160.                   CDEV.  During  this call data1 = WindowPtr.  In general, CDEVs can do any
  161.                   memory disposal and saving of settings during this call.  The disposal
  162.                   of the CDEV's controls is handled automatically by the Control Panel. */
  163.                 
  164.                 CloseCDEVProc();
  165.                 break;
  166.     
  167.             case EventsCDEV:    /* Message 6 */
  168.             
  169.                 /* if the wantEvents bit is set, the control panel will call this routine
  170.                   with data1 = ptr to the event record.  This allows the cdev to intercept
  171.                   and even *gasp* change the event record before it is handled by the
  172.                   control panel. */
  173.     
  174.                 EventsCDEVProc(data1);
  175.                 break;
  176.     
  177.             case CreateCDEV:    /* Message 7 */
  178.  
  179.                 /* if the wantCreate bit is set, this message is called with the control
  180.                   panel's Window ptr passed in data1.  The cdev must create any controls
  181.                   it has during this call.  The CDEV's resource fork is open during this
  182.                   call so resource manager calls can be made.  All controls rectangles
  183.                   MUST be relative to 0,0.  The control panel handles offsetting controls
  184.                   to the proper place in the Window.  Initialization of the controls
  185.                   needs to be done in the InitCDEV call.  Just create the controls in this
  186.                   call. */
  187.     
  188.                 CreateCDEVProc(data1);
  189.                 break;
  190.     
  191.             case AboutCDEV:    /* Message 8 */
  192.             
  193.                 /* if the wantAbout bit is set in the CDEV flags, this call is made when
  194.                   the user selects help.  Data1 = Window ptr to the help Window.  The
  195.                   control panel automatically handles the icon, author, and version #
  196.                   display.*/
  197.                 
  198.                 AboutCDEVProc(data1);
  199.                 break;
  200.     
  201.             case RectCDEV:    /* Message 9 */
  202.             
  203.                 /* if a CDEV has a different size data rectangle depending on some state,
  204.                   like the printer & modem port cdev's, then you can get a chance to tell the
  205.                   control panel this by setting the wantRect bit in the CDEV flags.  In
  206.                   this call, data1 is a ptr to the rect and can be directly modified by
  207.                   the CDEV. */
  208.     
  209.                 RectCDEVProc(data1);
  210.                 break;
  211.     
  212.             case HitCDEV:    /* Message 10 */
  213.             
  214.                 /* if the CDEV wants to know when a control has been "hit", it can set the
  215.                   wantHit bit in the CDEV flags.  When called, data1 = Hdl to Ctl Hit &
  216.                   data2 = Ctl ID of hit control.  This message allows the CDEV to perform
  217.                   actions based on the control that was selected by the user.*/
  218.                   
  219.                      HitCDEVProc (data2);
  220.                     break;
  221.                                             
  222.             case RunCDEV:    /* Message 11 */
  223.             
  224.                 /* This message is called if the "wantRun" bit is set in the CDEV flags.  It
  225.                   enables CDEVs like time to update the display.  It is called every 
  226.                   second - every time the DARun call is issued to the control panel. -no
  227.                   parameters are passed to this routine. */
  228.     
  229.                     RunCDEVProc();
  230.                     break;
  231.                     
  232.             case EditCDEV:    /* Message 12 */
  233.                     EditCDEVProc(data1,data2);
  234.                     break;
  235.                     
  236.         }    /* end of switch */
  237.     
  238.     RestoreDB(oldDBR);
  239.     
  240.     return(retCode);
  241.  
  242. }    /* end of CDEV function */
  243.  
  244.  
  245.  
  246.  
  247. /* MachineCDEV routine Message 1 */
  248.  
  249. int MachineCDEVProc()
  250. {    
  251.     int retCode;
  252.     
  253.     InitCursor();
  254.     AlertWindow (0x0000,NULL,"30/Message = MachineCDEV/^OK");
  255.     retCode = 1;        /* Set the retCode to non-zero value so CDEV is opened. */
  256.     return retCode;
  257. }
  258.  
  259. /* BootCDEV routine Message 2 */
  260. /* Look for the CDEV Icon at boot time */
  261.  
  262. /* Reserved Message 3 */
  263.  
  264. /* InitCDEV routine Message 4 */
  265.  
  266. InitCDEVProc(MyCDEVWindowPtr)
  267. WindowPtr    MyCDEVWindowPtr;
  268. {
  269.     HiliteControl (0x00FF,GetCtlHandleFromID(MyCDevWindowPtr,(long)NullEventCheckBox));
  270.     HiliteControl (0x00FF,GetCtlHandleFromID(MyCDevWindowPtr,(long)SwitchEventCheckBox));
  271.     HiliteControl (0x00FF,GetCtlHandleFromID(MyCDevWindowPtr,(long)DeskAccEventCheckBox));
  272.     HiliteControl (0x00FF,GetCtlHandleFromID(MyCDevWindowPtr,(long)DriverEventCheckBox));
  273.     InitCursor();
  274.     AlertWindow (0x0000,NULL,"30/Message = InitCDEV\rSome controls have been deactivated./^OK");
  275. }
  276.  
  277. /* CloseCDEV routine Message 5 */
  278.  
  279. CloseCDEVProc()
  280. {
  281.     if (OriginalKeyRepeatRate == 4)                                    /* Was the No Repeat set before we opened */
  282.         {
  283.             WriteBParam (0x0004,0x002D);                                /* Restore any changes to the BatteryRam */
  284.             UpdateSysBRam ();                                                /* Match the system to BatteryRam */
  285.         }
  286.     AlertWindow (0x0000,NULL,"30/Message = CloseCDEV/^OK");
  287. }
  288.  
  289. /* EventsCDEVProc Message 6 */
  290.  
  291. EventsCDEVProc(CDEVEventRecPtr)
  292. EventRecordPtr    CDEVEventRecPtr;
  293. {
  294.     myTaskRec = *(CDEVEventRecPtr);            /* Put the Event Record into a buffer */
  295.     switch (myTaskRec.what)                        /* Switch on the what field of that record */
  296.         {
  297.             case nullEvt:
  298.             NullEvtProc();
  299.             break;
  300.     
  301.             case mouseDownEvt:
  302.             MouseDownEvtProc();
  303.             break;
  304.         
  305.             case mouseUpEvt:
  306.             MouseUpEvtProc();
  307.             break;
  308.     
  309.             case keyDownEvt:
  310.             KeyDownEvtProc();
  311.             break;
  312.     
  313.             case autoKeyEvt:
  314.             AutoKeyEvtProc();
  315.             break;
  316.     
  317.             case updateEvt:
  318.             UpdateEvtProc();
  319.             break;
  320.     
  321.             case activateEvt:
  322.             ActivateEvtProc(myTaskRec);
  323.             break;
  324.     
  325.             case switchEvt:
  326.             break;
  327.     
  328.             case deskAccEvt:
  329.             break;
  330.     
  331.             case driverEvt:
  332.             break;
  333.     }
  334. }
  335.  
  336. /* CreateCDEV routine Message 7 */
  337.  
  338. CreateCDEVProc(ThisCDEVWindowPtr)
  339. WindowPtr    ThisCDEVWindowPtr;
  340. {
  341.     MyCDevWindowPtr = ThisCDEVWindowPtr;                                        /* Initialize global WindowPtr to returned Ptr from create */
  342.     SetBRAMProc();                                                                        /* Set AutoKey in BRAM if not already set and save old setting */
  343.     CDevCtlHandle = NewControl2(MyCDevWindowPtr,9,(long)myCtrlList);    /* Create all the resource controls */
  344.     TimeCtlHandle = NewControl2(MyCDevWindowPtr,0,&ASCIITimeCtl);        /* Create the time control only (defined on the stack) */
  345. }
  346.  
  347. /* AboutCDEV routine Message 8 */
  348.  
  349. AboutCDEVProc(AboutWIndowPtr)
  350. WindowPtr    AboutWIndowPtr;
  351. {
  352.     AboutBoxCtlHandle = NewControl2(AboutWIndowPtr,2,(long)AboutID);
  353. }
  354.  
  355. /* RectCDEV routine Message 9 */
  356.  
  357. RectCDEVProc(RectPtr)
  358. pointer    RectPtr;
  359. {
  360.     InitCursor();
  361.     AlertWindow (0x0000,NULL,"40/Message = RectCDEV\rThe CDEV window Rect is being resized to:\r{0,0,200,165}.\rThe Rect in the CDEV resource is:\r{0,0,200,175}/^OK");
  362.     SetRect (RectPtr,0,0,200,150);
  363. }
  364.  
  365. /* HitCDEV routine Message 10 */
  366.  
  367. HitCDEVProc(MyControlID)                
  368. long    MyControlID;
  369. {
  370.     if (MyControlID == CheckABoxText)
  371.         {
  372.             AlertWindow (0x0000,NULL,"30/Message = HitCDEV\rControl Hit = CheckABoxText/^OK");
  373.         }
  374.     else if (MyControlID == ASCIITimeStaticText)
  375.         {
  376.             AlertWindow (0x0000,NULL,"30/Message = HitCDEV\rControl Hit = ASCIITimeStaticText/^OK");
  377.         }
  378. }
  379.  
  380. /* RunCDEV routine Message 11 */
  381.  
  382. RunCDEVProc()
  383. {
  384.     int    i;
  385.     
  386.     if (FrontWindow() == MyCDevWindowPtr)
  387.         {
  388.             ReadAsciiTime (ASCIITimeText);
  389.             for (i = 0; i < 20; i++)
  390.                 {
  391.                     ASCIITimeText[i] = ASCIITimeText[i]&0x7F;
  392.                 }
  393.             DrawOneCtl(TimeCtlHandle);
  394.         };
  395. }
  396.  
  397. /* EditCDEVProc Message 12 */
  398.  
  399. EditCDEVProc(EditCode,EditCDEVWindowPtr)
  400. long            EditCode;
  401. WindowPtr    EditCDEVWindowPtr;
  402. {
  403.     static char    AlertString[175];
  404.     
  405.     if(EditCode == 0x0005)
  406.     {
  407.         sprintf(AlertString,"30/Message = EditCDEV\rEditCode = $%lxL (Undo)\rWindow Pointer = $%lxL/^#OK",
  408.             EditCode,
  409.             EditCDEVWindowPtr);
  410.         AlertWindow (0x0000,NULL,AlertString);
  411.     }
  412.     
  413.     if(EditCode == 0x0006)
  414.     {
  415.     sprintf(AlertString,"30/Message = EditCDEV\rEditCode = $%lxL (Cut)\rWindow Pointer = $%lxL/^#OK",
  416.             EditCode,
  417.             EditCDEVWindowPtr);
  418.         AlertWindow (0x0000,NULL,AlertString);
  419.     }
  420.     
  421.     if(EditCode == 0x0007)
  422.     {
  423.         sprintf(AlertString,"30/Message = EditCDEV\rEditCode = $%lxL (Copy)\rWindow Pointer = $%lxL/^#OK",
  424.             EditCode,
  425.             EditCDEVWindowPtr);
  426.         AlertWindow (0x0000,NULL,AlertString);
  427.     }
  428.  
  429.     if(EditCode == 0x0008)
  430.     {
  431.         sprintf(AlertString,"30/Message = EditCDEV\rEditCode = $%lxL (Paste)\rWindow Pointer = $%lxL/^#OK",
  432.             EditCode,
  433.             EditCDEVWindowPtr);
  434.         AlertWindow (0x0000,NULL,AlertString);
  435.     }
  436.     
  437.     if(EditCode == 0x0009)
  438.     {
  439.         sprintf(AlertString,"30/Message = EditCDEV\rEditCode = $%lxL (Clear)\rWindow Pointer = $%lxL/^#OK",
  440.             EditCode,
  441.             EditCDEVWindowPtr);
  442.         AlertWindow (0x0000,NULL,AlertString);
  443.     }
  444. }
  445.  
  446. /* Here's all the Event Handling Procs */
  447.  
  448. NullEvtProc()
  449. {
  450.     if (GetCtlValue(GetCtlHandleFromID(MyCDevWindowPtr,(long)NullEventCheckBox)) != 0)
  451.         {
  452.             AlertWindow (0x0000,NULL,"30/Message = EventsCDEV\rEvent Code = nullEvt/^OK");
  453.             ResetControls();
  454.         }
  455. }
  456.  
  457. MouseDownEvtProc()
  458. {
  459.     if (GetCtlValue(GetCtlHandleFromID(MyCDevWindowPtr,(long)MouseDownEventCheckBox)) != 0)
  460.         {
  461.             AlertWindow (0x0000,NULL,"30/Message = EventsCDEV\rEvent Code = mouseDownEvt/^OK");
  462.             ResetControls();
  463.         }
  464. }
  465.  
  466. MouseUpEvtProc()
  467. {
  468.     if (GetCtlValue(GetCtlHandleFromID(MyCDevWindowPtr,(long)MouseUpEventCheckBox)) != 0)
  469.         {
  470.             AlertWindow (0x0000,NULL,"30/Message = EventsCDEV\rEvent Code = mouseUpEvt/^OK");
  471.             ResetControls();
  472.         }
  473. }
  474.  
  475. KeyDownEvtProc()
  476. {
  477.     if (GetCtlValue(GetCtlHandleFromID(MyCDevWindowPtr,(long)KeyDownEventCheckBox)) != 0)
  478.         {
  479.             AlertWindow (0x0000,NULL,"30/Message = EventsCDEV\rEvent Code = keyDownEvt/^OK");
  480.             ResetControls();
  481.         }
  482. }
  483.  
  484. AutoKeyEvtProc()
  485. {
  486.     if (GetCtlValue(GetCtlHandleFromID(MyCDevWindowPtr,(long)AutoKeyEventCheckBox)) != 0)
  487.         {
  488.             AlertWindow (0x0000,NULL,"30/Message = EventsCDEV\rEvent Code = autoKeyEvt/^OK");
  489.             ResetControls();
  490.         }
  491. }
  492.  
  493. UpdateEvtProc()
  494. {
  495.     if (GetCtlValue(GetCtlHandleFromID(MyCDevWindowPtr,(long)UpdateEventCheckBox)) != 0 && UpdateFlag == 0)
  496.         {
  497.             ++UpdateFlag;
  498.             AlertWindow (0x0000,NULL,"30/Message = EventsCDEV\rEvent Code = updateEvt/^OK");
  499.             UpdateFlag = 0;
  500.             ResetControls();
  501.         }
  502. }
  503.  
  504. ActivateEvtProc(myTaskRec)
  505. WmTaskRec    myTaskRec;
  506. {
  507.     if (GetCtlValue(GetCtlHandleFromID(MyCDevWindowPtr,(long)ActivateEventCheckBox)) != 0)
  508.         {
  509.             if ((myTaskRec.modifiers&0x0001) != 0)
  510.                 {
  511.                     AlertWindow (0x0000,NULL,"30/Message = EventsCDEV\rEvent Code = activateEvt/^OK");
  512.                     ResetControls();
  513.                 }
  514.             else if ((myTaskRec.modifiers&0x0001) == 0)
  515.                 {
  516.                     AlertWindow (0x0000,NULL,"30/Message = EventsCDEV\rEvent Code = deactivateEvt/^OK");
  517.                 }
  518.         }
  519. }
  520.  
  521. /* A routine to reset controls state so that some events don't pile up */
  522.  
  523. ResetControls ()
  524. {
  525.     SetCtlValue (0,GetCtlHandleFromID(MyCDevWindowPtr,(long)NullEventCheckBox));
  526.     SetCtlValue (0,GetCtlHandleFromID(MyCDevWindowPtr,(long)MouseDownEventCheckBox));
  527.     SetCtlValue (0,GetCtlHandleFromID(MyCDevWindowPtr,(long)MouseUpEventCheckBox));
  528.     SetCtlValue (0,GetCtlHandleFromID(MyCDevWindowPtr,(long)KeyDownEventCheckBox));
  529.     SetCtlValue (0,GetCtlHandleFromID(MyCDevWindowPtr,(long)AutoKeyEventCheckBox));
  530.     SetCtlValue (0,GetCtlHandleFromID(MyCDevWindowPtr,(long)UpdateEventCheckBox));
  531.     SetCtlValue (0,GetCtlHandleFromID(MyCDevWindowPtr,(long)ActivateEventCheckBox));
  532.     /*
  533.     SetCtlValue (0,GetCtlHandleFromID(MyCDevWindowPtr,(long)SwitchEventCheckBox));
  534.     SetCtlValue (0,GetCtlHandleFromID(MyCDevWindowPtr,(long)DeskAccEventCheckBox));
  535.     SetCtlValue (0,GetCtlHandleFromID(MyCDevWindowPtr,(long)DriverEventCheckBox));
  536.     */
  537. }
  538.  
  539. /* Routine to set BRAM to allow autokey and save old BRAM setting */
  540.  
  541. SetBRAMProc()
  542. {
  543.     if (ReadBParam (0x002D) == 0x0004)        /* Is the No-Repeat set? */
  544.         {
  545.             OriginalKeyRepeatRate = 4;            /* Initialize storage variable */
  546.             WriteBParam (0x0002,0x002D);        /* If so, change it to 0.75 sec delay. */
  547.             UpdateSysBRam ();
  548.         }
  549. }
  550.  
  551. /* This routine updates the RAM coppy of the BRAM parameters to match the BRAM. */
  552.  
  553. UpdateSysBRam ()
  554. {
  555.     asm                                /* Update RAM copy of parameter-RAM */
  556.     {
  557.         phd                        /* save direct page register word on stack            */
  558.         phb                        /* save data bank register byte on stack            */
  559.         pea #0x0                /* push two bytes of 0 on the stack                    */
  560.         plb                        /* set data bank register byte to 0                    */
  561.         plb                        /* clean up extraneous byte from stack                */
  562.         php                        /* save processor status register byte on stack        */
  563.         sep #0x30                /* set processor status to shortm+shortx            */
  564.         sec                        /* set carry so ToBRAMSetup won't alter slot setup    */
  565.         jsl 0xE10094            /* call ToBRAMSetup                                    */
  566.         plp                        /* restore processor status mode byte from stack    */
  567.         plb                        /* restore data bank register byte from stack        */
  568.         pld                        /* restore direct page register word from stack        */
  569.     }
  570. }
  571.  
  572.